###################################################################### Product:      KnowledgeEngine (Plone Edition)## File:         Action.py## Copyright:    Copyright (c) 2004, Faulkner Technologies## Author:       Brian Oliver## Description:  This file defines the abstract Action class, the #               base class of all Actions.##               Actions are a primitive Objects that perform some type#               of end-user defined task, typically when some#               event occurs.## See Also:     GenericObject, Event#####################################################################
####################################################################### Knowledge Engine Library Importsfrom Common import *from GenericObject import GenericObject, GenericObjectInfofrom Products.KnowledgeEngine.PropertyDefinition import *from Products.KnowledgeEngine.PropertyTypes import *from Products.KnowledgeEngine.PropertyFormats import *from Products.KnowledgeEngine.PropertyStructures import *from Products.KnowledgeEngine.KERLProcessor import *from Products.KnowledgeEngine.KERFProcessor import *
####################################################################### Zope Library Importsfrom Globals import DTMLFilefrom App.ImageFile import ImageFilefrom Acquisition import *
####################################################################### Python Library Imports# (none)
####################################################################### The Standard Action Types ## (see also: Event types in EventDefinition class)at_SERVER = 1at_BROWSER = 2
####################################################################### ElementInfo Class Definitionclass ActionInfo(GenericObjectInfo):    """        Defines the class info methods, defining information about        the class without needing an instance of the class    """        #---------------------------------------------------------------#        def getClassName(self):        """            Returns the name of the class for which             we are providing information.        """        return 'Action'
    #---------------------------------------------------------------#    
    def getClassFamilyName(self):        """            Return the name of the family to which the the            class (and subclasses) and it's subclasses belong/                        This is used to enable searching for families of             generic objects, eg: 'EntitySource' instances.        """        #all entity sources belong to the 'EntitySource' family        return 'Action'    #---------------------------------------------------------------#        def getDisplayName(self):        """            Return a friendly name for the class instances            (this is used for displaying in lists etc)        """            return "Action"            #---------------------------------------------------------------#    
    def getIdentityType(self):        """            Return the identity type.          """                return "action"    
    #---------------------------------------------------------------#    
    def isInstanceOf(self, className):        """            Returns if the class is an instance of the specified            className, or implements the interface specified             by the className        """        
        return className == 'Action' or GenericObjectInfo.isInstanceOf(self, className)        
    #---------------------------------------------------------------#    
    def isContainer(self):        """            Returns if the instance is providing folderish/container            services.                        Override an return true if the instance is to be            a container for other instances.                        NOTE: all instances support "events" so there is no            need to return true if you require "event" support.        """        
        #by default, actions aren't containers        return false                      #---------------------------------------------------------------#    
    def isPermittedInContainer(self, containerClassInfo, containerInstance = None, instance=None):        """            ABSTRACT: Returns if class instances (instance) is permitted in             the specified container (containerInstance)                        NOTE: This is from this class' instance perspective.        """                #DEFAULT RULE: Actions are only permitted in Events, AssessmentActions and Actions that are containers (that are of compatible types)        if containerInstance != None:            return (containerClassInfo.isInstanceOf("Action") and containerClassInfo.isContainer() and ((containerInstance.getClassInfo().getType() and self.getType()) <> false)) or \                   (containerClassInfo.isInstanceOf('Event') and ((containerInstance.getDefinition().getType() and self.getType()) <> false)) or \                   (containerClassInfo.isInstanceOf('AssessmentAction') and ((containerInstance.getClassInfo().getType() and self.getType()) <> false))        else:            return (containerClassInfo.isInstanceOf("Action") and containerClassInfo.isContainer()) or \                   containerClassInfo.isInstanceOf('Event')  or \                   containerClassInfo.isInstanceOf('AssessmentAction')            
    #---------------------------------------------------------------#    
    def isChildPermitted(self, childClassInfo, childInstance = None):        """            Returns if the specified child is permitted as a             child of the class' instances.                        NOTE: This is from this class' instance perspective.                        For component containers, this always overrides what the            return value from childClassInfo.isPermittedInContainer(...)        """                #DEFAULT RULE: Actions can have Children if they are containers        return self.isContainer() and childClassInfo.isInstanceOf("Action")                #---------------------------------------------------------------#    
    def onConfigureProperties(self):        """            Automatically called by the Knowledge Engine once            the class has been loaded.  Use this method to register             class specific properties using the PropertyReflection interface.                        If this class is sub-classed, a call must be made to            the super-class to ensure super-class properties are            correctly registered                        NOTE: This method is called before ClassInfo.onAfterStartup()                    """        
        #initialise the super-class properties for reflection        GenericObjectInfo.onConfigureProperties(self)                #hide the identity property        self.getPropertyDefinition('identity').setPropertyEditorEVAP(evap_READONLY)        
        #add the 'order' property                self.addPropertyDefinition(PropertyDefinition(identity="order",                                                       displayName="Order",                                                       description="The relative position of the action with in it's container",                                                       defaultValue=1.0,                                                       propertyType=pt_FLOAT,                                                       propertyFormat=pf_NATIVE,                                                       propertyStructure=ps_ATOMIC,                                                       constructorEVAP=evap_NONE,                                                       propertyEditorEVAP=evap_NONE))                #---------------------------------------------------------------#    
    def onConfigurePermissions(self):        """            Automatically called by the Knowledge Engine once            the class has been loaded.  Use this method to register             class specific permission definitions.                        If this class is sub-classed, a call must be made to            the super-class to ensure super-class properties are            correctly registered                        NOTE: This method is called before ClassInfo.onAfterStartup()                    """        
        #initialise the super-class events for reflection        GenericObjectInfo.onConfigurePermissions(self)        #---------------------------------------------------------------#    
    def getType(self):        """            Return the where the Action instances of this class            may be executed; at_SERVER and at_BROWSER are valid types            This is directly related to the Event types.  Action            types may be order together if they support multiple            locations of execution.        """                return at_SERVER            #---------------------------------------------------------------#    
####################################################################### Action Class Definitionclass Action(GenericObject):    """        Base class for all KnowledgeEngine Actions    """    
    #---------------------------------------------------------------#
    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class    _CLASSINFO = ActionInfo()    
    #---------------------------------------------------------------#    
    def __init__(self, id, identity):        "Constructor for the Element"                        GenericObject.__init__(self, id, identity)        
    #---------------------------------------------------------------#    
    def onAfterInstanciation(self):        """            Handle Knowledge Engine specific actions after this object             has been loaded into memory.                          This is useful for performing backwards compatibility        """        
        #preform default onAfterInstanciation processing        GenericObject.onAfterInstanciation(self)                ###print "DEBUG: Element.onAfterInstanciation: Completed"            #---------------------------------------------------------------#    
    def isOrderedContainer(self):        """            Return if the children of the object may use ordering.                        This is to allow the 'Order' column in the Content            management tab in Zope                    """        
        #if we are a container then we are ordered.        return self.isContainer()            #---------------------------------------------------------------#    
    def isPreviewPermitted(self):        """            Return if the Element is allowed to be previewed.                        By default all elements can't be previewed, some however            should can be previewed. eg: HTMLHeaderFooters        """                return false            #---------------------------------------------------------------#        def execute(self, assessment, user = None, previousActionSuccess = true):        """            ABSTRACT: Attempts to execute the defined action             (on the SERVER), returning true if the action performed             some task or false if no tasks where executed/there was an error                        NOTE: The action is executed using the permissions of the            specified Knowledge Engine User.                        previousActionSuccess: specifies if the immediate action at the same level was successful.        """                    
        #execute the child actions if the action is a container        if self.isContainer():            #get the actions for the event (in order)            actions = self.getChildrenByOrder()            
            #(assume the last action was successful... at the start of a new container)            lLastActionSuccess = true                        for action in actions:
                #execute the current action                lLastActionSuccess = action.execute(assessment, user, lLastActionSuccess)                
            #(containers by default are always successfull at executing)            return true                    else:            #by default we haven't executed anything            return false            #---------------------------------------------------------------#    ####################################################################### Class Initialisation# (none)
